/**
 * 语音服务
 * 封装语音识别和语音播放功能
 */

import Tts from 'react-native-tts';
import Sound from 'react-native-sound';
import { Platform } from 'react-native';
import iflytekRealtimeAsrService from './iflytekRealtimeAsrService';
import iflytekTtsService from './iflytekTtsService';
import iflytekHttpTtsService from './iflytekHttpTtsService';
import baiduTtsService from './baiduTtsService';
import trackPlayerService from './trackPlayerService';

class VoiceService {
  constructor() {
    this.isInitialized = false;
    this.currentSound = null;
    this.currentAudioUrl = null; // 记录当前音频URL，防止重复加载
    this.isListening = false;
    this.isSpeaking = false;
    this.ttsReady = false;

    // 用于取消进行中的TTS任务的会话ID与AbortController（特别是百度TTS的HTTP请求）
    this._speakSessionId = 0;
    this._currentTtsAbortController = null;

    // TTS引擎选择：'system'、'baidu'、'iflytek'（WebSocket）或 'iflytek-http'（HTTP API，暂不可用）
    // 使用 baidu：音质自然，情感丰富（需要 react-native-fs 支持，重新编译后可用）
    this.ttsEngine = 'baidu'; // 默认使用百度TTS（自然语音）

    // 讯飞TTS参数配置
    this.iflytekTtsConfig = {
      voiceName: 'aisxping', // 温暖女声，可选：xiaoyan(温柔女声)、aisjiuxu(情感男声)
      speed: 50, // 语速 0-100
      volume: 80, // 音量 0-100
      pitch: 50, // 音高 0-100
    };

    // 百度TTS参数配置
    this.baiduTtsConfig = {
      voiceName: '4', // 0(女声基础), 1(男声基础), 3(情感男声), 4(情感女声), 5(度小宇), 106(情感女声)
      speed: '5', // 语速 0-15，默认5
      volume: '9', // 音量 0-15，默认5
      pitch: '5', // 音调 0-15，默认5
    };

    // 语音识别回调
    this.onSpeechResults = null;
    this.onSpeechError = null;
    this.onSpeechStart = null;
    this.onSpeechEnd = null;
  }

  /**
   * 设置TTS引擎
   * @param {'system'|'baidu'|'iflytek'|'iflytek-http'} engine - TTS引擎类型
   */
  setTtsEngine(engine) {
    this.ttsEngine = engine;
  }

  /**
   * 设置百度TTS参数
   * @param {Object} config - TTS配置
   */
  setBaiduTtsConfig(config) {
    this.baiduTtsConfig = { ...this.baiduTtsConfig, ...config };
  }

  /**
   * 设置讯飞TTS参数
   * @param {Object} config - TTS配置
   */
  setIflytekTtsConfig(config) {
    this.iflytekTtsConfig = { ...this.iflytekTtsConfig, ...config };
  }

  /**
   * 初始化语音服务
   */
  async initialize() {
    if (this.isInitialized) return;

    Sound.setCategory('Playback');
    this.isInitialized = true;
  }

  async ensureTtsReady() {
    if (this.ttsReady) {
      return;
    }
    await Tts.getInitStatus();

    // 设置中文语言
    if (Platform.OS === 'ios') {
      await Tts.setDefaultLanguage('zh-CN');
    } else {
      await Tts.setDefaultLanguage('zh_CN');
    }

    // 优化语音参数，使其更自然
    await Tts.setDefaultRate(0.52); // 稍微加快一点（0.5太慢，0.6太快）
    await Tts.setDefaultPitch(1.05); // 稍微提高音调，更自然

    // iOS特有：设置语音质量
    if (Platform.OS === 'ios') {
      try {
        // 尝试设置更好的语音质量
        await Tts.setDefaultVoice('com.apple.ttsbundle.Tingting-compact'); // Tingting是iOS中文女声
      } catch {}
    }

    this.ttsReady = true;
  }

  /**
   * 开始语音识别
   * @param {Object} callbacks - 回调函数
   */
  async startListening(callbacks = {}) {
    if (!this.isInitialized) {
      await this.initialize();
    }

    if (this.isListening) {
      return;
    }

    try {
      await this.stopSpeaking();
      this.isListening = true;

      if (callbacks.onStart) {
        callbacks.onStart();
      }

      await iflytekRealtimeAsrService.startListening({
        onPartial: text => {
          if (callbacks.onResults) {
            callbacks.onResults(text, { isFinal: false });
          }
        },
        onFinal: text => {
          if (callbacks.onResults) {
            callbacks.onResults(text, { isFinal: true });
          }
        },
        onError: error => {
          this.isListening = false;
          if (callbacks.onError) {
            callbacks.onError(error);
          }
        },
        onClose: () => {
          this.isListening = false;
          if (callbacks.onEnd) {
            callbacks.onEnd();
          }
        },
      });
    } catch (error) {
      this.isListening = false;
      if (callbacks.onError) {
        callbacks.onError(error);
      }
      throw error;
    }
  }

  /**
   * 停止语音识别
   */
  async stopListening() {
    if (!this.isListening) {
      return;
    }

    try {
      await iflytekRealtimeAsrService.stopListening();
      this.isListening = false;
    } catch {
      // Ignore stop listening errors
    }
  }

  /**
   * 播放文字语音（使用TTS）
   * @param {string} text - 要播放的文字
   * @returns {Promise} - 播放完成时 resolve
   */
  async speak(text) {
    if (!this.isInitialized) {
      await this.initialize();
    }

    // 启动新会话，用于取消后续的过期任务
    const sessionId = ++this._speakSessionId;

    try {
      // 停止当前播放（这也会使之前的会话失效）
      await this.stopSpeaking();
      this.isSpeaking = true;

      // 根据选择的引擎播放语音
      if (this.ttsEngine === 'baidu') {
        // 使用可取消的Fetch，避免关闭弹窗后仍继续合成并播放
        let controller = null;
        try {
          controller = new AbortController();
          this._currentTtsAbortController = controller;
        } catch (e) {
          // 兼容旧环境没有 AbortController 的情况
          controller = null;
          this._currentTtsAbortController = null;
        }

        // 1) 合成音频
        const audioData = await baiduTtsService.synthesize(text, {
          ...this.baiduTtsConfig,
          fetchSignal: controller ? controller.signal : undefined,
        });

        // 如果在合成期间被取消（会话变更或abort），则不再播放
        if ((controller && controller.signal.aborted) || sessionId !== this._speakSessionId) {
          this.isSpeaking = false;
          // 清理引用
          if (this._currentTtsAbortController === controller) this._currentTtsAbortController = null;
          return;
        }

        // 2) 播放音频（播放前再次确认会话未被取消）
        await baiduTtsService.playAudioBuffer(audioData);
        this.isSpeaking = false;
        if (this._currentTtsAbortController === controller) this._currentTtsAbortController = null;
        return;
      }

      if (this.ttsEngine === 'iflytek-http') {
        await iflytekHttpTtsService.speak(text, this.iflytekTtsConfig);
        this.isSpeaking = false;
        return;
      }

      if (this.ttsEngine === 'iflytek') {
        await iflytekTtsService.speak(text, this.iflytekTtsConfig);
        this.isSpeaking = false;
        return;
      }

      // 使用系统TTS
      await this.ensureTtsReady();

      // 返回一个 Promise，等待播放完成
      return new Promise((resolve, reject) => {
        // 监听播放完成事件
        const finishListener = Tts.addEventListener('tts-finish', () => {
          this.isSpeaking = false;
          finishListener?.remove();
          errorListener?.remove();
          resolve();
        });

        // 监听播放错误事件
        const errorListener = Tts.addEventListener('tts-error', () => {
          this.isSpeaking = false;
          finishListener?.remove();
          errorListener?.remove();
          reject(new Error('TTS 播放失败'));
        });

        // 开始播放
        Tts.speak(text)
          .then(() => {})
          .catch(error => {
            this.isSpeaking = false;
            finishListener?.remove();
            errorListener?.remove();
            reject(error);
          });
      });
    } catch (error) {
      this.isSpeaking = false;
      throw error;
    }
  }

  /**
   * 停止播放语音
   */
  async stopSpeaking() {
    // 取消百度TTS合成中的网络请求（如果存在）
    if (this._currentTtsAbortController) {
      try {
        this._currentTtsAbortController.abort();
      } catch {}
      this._currentTtsAbortController = null;
    }

    if (!this.isSpeaking) return;

    try {
      // 停止百度TTS
      if (this.ttsEngine === 'baidu') {
        await baiduTtsService.stop();
      }
      // 停止讯飞HTTP TTS
      else if (this.ttsEngine === 'iflytek-http') {
        iflytekHttpTtsService.stop();
      }
      // 停止讯飞WebSocket TTS
      else if (this.ttsEngine === 'iflytek') {
        iflytekTtsService.stop();
      }
      // 停止系统TTS
      else if (this.ttsReady) {
        await Tts.stop();
      }
      this.isSpeaking = false;
    } catch {
      // Ignore TTS stop errors
    }
  }

  /**
   * 播放音频文件（使用 TrackPlayer）
   * @param {string} audioUrl - 音频文件路径或URL
   * @param {Function} onStart - 播放开始回调
   * @param {Function} onComplete - 播放完成回调
   * @param {Object} metadata - 音频元数据 { title, artist, artwork, duration }
   */
  async playAudio(audioUrl, onStart, onComplete, metadata = {}) {
    if (!audioUrl) {
      if (onStart) onStart(new Error('没有音频URL'));
      return;
    }

    try {
      // 记录当前URL
      this.currentAudioUrl = audioUrl;

      // 标记有音频对象（用于兼容性检查）
      this.currentSound = { url: audioUrl };

      // 添加或更新 Track（2.x 版本最小化配置，只传递url/title/artist）
      await trackPlayerService.addOrUpdateTrack({
        url: audioUrl,
        title: metadata.title || '景区音频',
        artist: metadata.artist || '山猫导游',
      });

      // 开始播放
      await trackPlayerService.play();

      // 调用开始回调
      if (onStart) {
        onStart(null);
      }


      // 注意：播放完成回调由 AudioPlayerContext 监听 TrackPlayer 事件处理
      // 这里保存 onComplete 供后续使用
      this.onPlayComplete = onComplete;
    } catch (error) {
      console.error('❌ TrackPlayer 播放失败:', error);
      this.currentSound = null;
      if (onStart) onStart(error);
    }
  }

  /**
   * 停止播放音频（使用 TrackPlayer）
   */
  async stopAudio() {

    try {
      await trackPlayerService.stop();
      this.currentSound = null;
      this.currentAudioUrl = null;
    } catch (error) {
      console.error('❌ TrackPlayer 停止失败:', error);
    }
  }

  /**
   * 暂停播放音频（使用 TrackPlayer）
   */
  async pauseAudio() {
    try {
      await trackPlayerService.pause();
    } catch (error) {
      console.error('❌ TrackPlayer 暂停失败:', error);
    }
  }

  /**
   * 恢复播放音频（使用 TrackPlayer）
   * @param {Function} onStart - 播放开始回调
   * @param {Function} onComplete - 播放完成回调
   */
  async resumeAudio(onStart, onComplete) {
    try {
      await trackPlayerService.play();

      if (onStart) {
        onStart(null);
      }

    } catch (error) {
      console.error('❌ TrackPlayer 恢复播放失败:', error);
      if (onStart) {
        onStart(error);
      }
    }
  }

  /**
   * 获取当前音频时长（使用 TrackPlayer）
   * @returns {Promise<number>} 时长（秒）
   */
  async getDuration() {
    try {
      return await trackPlayerService.getDuration();
    } catch (error) {
      return 0;
    }
  }

  /**
   * 获取当前播放位置（使用 TrackPlayer）
   * @param {Function} callback - 回调函数，参数为当前位置（秒）
   */
  async getCurrentTime(callback) {
    try {
      const position = await trackPlayerService.getPosition();
      if (callback) {
        callback(position);
      }
      return position;
    } catch (error) {
      if (callback) {
        callback(0);
      }
      return 0;
    }
  }

  /**
   * 设置播放位置（使用 TrackPlayer）
   * @param {number} time - 目标时间（秒）
   */
  async setCurrentTime(time) {
    try {
      await trackPlayerService.seekTo(time);
    } catch (error) {
      console.error('❌ 设置播放位置失败:', error);
    }
  }

  /**
   * 清理 TTS 资源（语音识别和TTS播报）
   * 用于弹窗关闭时，不影响音频文件播放
   */
  async cleanupTts() {
    try {
      await this.stopListening();
      await this.stopSpeaking();

      // 清理TTS资源（使用 await 确保完全停止）
      await baiduTtsService.cleanup();
      await iflytekTtsService.cleanup();
      await iflytekHttpTtsService.cleanup();

      this.onSpeechResults = null;
      this.onSpeechError = null;
      this.onSpeechStart = null;
      this.onSpeechEnd = null;
    } catch {
      // Ignore cleanup errors
    }
  }

  /**
   * 清理音频资源（音频文件播放）
   */
  cleanupAudio() {
    try {
      this.stopAudio();
    } catch {
      // Ignore cleanup errors
    }
  }

  /**
   * 清理所有资源（TTS + 音频）
   */
  async cleanup() {
    try {
      await this.cleanupTts();
      this.cleanupAudio();
    } catch {
      // Ignore cleanup errors
    }
  }

  /**
   * 销毁服务
   */
  async destroy() {
    await this.cleanup();
    this.isInitialized = false;
  }
}

// 导出单例
const voiceService = new VoiceService();
export default voiceService;
